home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’93 / The Regulator 1.4 / PB.c < prev    next >
Text File  |  1993-06-04  |  7KB  |  303 lines

  1. /*
  2. ** PB.c
  3. **
  4. ** PowerBook specific routines for setting & getting various sleep and rest values.
  5. ** of course, any of these can change at any time, and they aren't official
  6. ** nor from Apple.  I figured these out by disassembling code.  This stuff WILL
  7. ** change in the future.  Don't base any products on this, or you'll be very
  8. ** sorry (and DTS will laugh in your face…)  Don't ask Apple for help on this
  9. ** stuff… they have no further information they are willing to disclose.
  10. */
  11. #include "XPRAM.h"
  12. #include <Power.h>
  13. #include <GestaltEqu.h>
  14. #include <SegLoad.h>
  15. #include <Folders.h>
  16. #include <Files.h>
  17. #include <Memory.h>
  18. #include <Resources.h>
  19.  
  20. #ifdef THINK_C
  21. /* These are defined in MPW C 3.2.3, but not in Think C 5.0.2 */
  22. #define    gestaltPowerBook100        24    /* not defined in GestaltEqu.h */
  23. #define    gestaltPowerBook140        25    /* not defined in GestaltEqu.h */
  24. #define gestaltPowerBook145        54
  25. #define    gestaltPowerBook170        21    /* not defined in GestaltEqu.h */
  26. #define    gestaltDuo230            29
  27. #define    gestaltDuo210            32
  28. #define    gestaltPowerBook180        33
  29. #define    gestaltPowerBook160        34
  30. #define    gestaltPowerBook165c    50
  31. #endif
  32.  
  33. #define    kUnitsOfSleep        (60/15)        /* empirical from source */
  34. #define kMaxSysSleep        15*kUnitsOfSleep
  35. #define kMaxHDSleep            15*kUnitsOfSleep
  36. #define kByteSize            1
  37.  
  38. /* globals */
  39. Boolean    gOnBattery;        /* charger connection determines this */
  40. short    gFlagsLocation;
  41. Byte    gSysSleep;
  42. Byte    gHDSleep;
  43.  
  44. /* procedures declared in this module */
  45. OSErr    CheckForMains();
  46. void    SetPMgrDirty();
  47. Boolean    ToggleFlag(short, Byte, Boolean);
  48. Boolean    SetDontRest();
  49. Boolean    SetRest();
  50. // Byte    GetUserSysSleep();
  51. // Byte    GetUserHDSleep();
  52. void    SetSysSleep();
  53. void    SetHDSleep();
  54. void    InitPortableStuff();
  55. void    InitPrefs();
  56.  
  57. /* CheckForMains
  58.  *
  59.  * This is the routine we invoke when called periodically.
  60.  * Check for battery status.  if we've recently been plugged in, modify
  61.  * the idle state.
  62.  */
  63.  
  64. OSErr
  65. CheckForMains()
  66. {
  67.     Byte    status;
  68.     Byte    power;
  69.     Boolean    currentlyConnected;
  70.     OSErr    err;
  71.     
  72.     err = BatteryStatus(&status, &power);
  73.     if ( noErr == err ) 
  74.     {
  75.         currentlyConnected = status & chargerConnMask;
  76.         if (currentlyConnected != gOnBattery)
  77.         {
  78.             if (!currentlyConnected) {    /* we just got disconnected from the mains */
  79.                 SetRest();
  80.                 SetSysSleep(gSysSleep);
  81.                 SetHDSleep(gHDSleep);
  82.             }
  83.             else {                    /* we just connected to the mains */
  84.                 SetDontRest();
  85.                 //gSysSleep = GetUserSysSleep();
  86.                 //gHDSleep = GetUserHDSleep();
  87.                 SetSysSleep(kMaxSysSleep);
  88.                 SetHDSleep(kMaxHDSleep);
  89.             }
  90.             gOnBattery = currentlyConnected;
  91.         }
  92.     }
  93.     return err;
  94. }
  95.  
  96.  
  97.  
  98. /* Set the Power Manager's dirty byte whenever anything changes */
  99. void SetPMgrDirty()
  100. {
  101.         PMgrLocal(TOdirtyFlag) = 0xff; /* set the byte */
  102. }
  103.  
  104. /*
  105.  * Toggle a flag in prFlags
  106.  * Return the new state of the flag
  107.  */
  108. Boolean ToggleFlag(short flagPramAddr,Byte bit, Boolean newState)
  109.     {
  110.     Byte scratch;
  111.     
  112.     ReadPRAM(flagPramAddr, kByteSize, (char *)&scratch);    /* Read the current state */
  113.  
  114.     if (newState)
  115.         scratch |= bit;
  116.     else
  117.         scratch &= ~bit;
  118.  
  119.     SetPRAM(flagPramAddr, kByteSize, (char *)&scratch);            /* Put it back */
  120.     SetPMgrDirty();                                /* Tell PMgr to notice the change */
  121.     return newState;                            /* return the new state */
  122.     }
  123.  
  124. /*
  125.  * Set the "Don't Rest while plugged in" flag in PRAM
  126.  */
  127. Boolean SetDontRest()
  128. {
  129.     Boolean    result;
  130.     
  131.     result = ToggleFlag(gFlagsLocation,kPowerSave, true);
  132.     return result;
  133. }
  134.  
  135. /*
  136.  * Set the "Rest while plugged in" flag in PRAM
  137.  */
  138. Boolean SetRest()
  139. {
  140.     Boolean    result;
  141.     
  142.     result = ToggleFlag(gFlagsLocation,kPowerSave, false);
  143.     return result;
  144. }
  145.  
  146. #if 0
  147.  
  148. /*
  149. ** GetUserSysSleep
  150. ** read the PRAM and return what the user set gSysSleep to be
  151. */
  152. Byte GetUserSysSleep()
  153. {
  154.     Byte    scratch;
  155.     
  156.     ReadPRAM(PRAM_BASE+prSysSleep_Offset, kByteSize, (char *)&scratch);
  157.     return scratch;
  158. }
  159.  
  160. /*
  161. ** GetUserHDSleep
  162. ** read the PRAM and return what the user set gHDSleep to be
  163. */
  164. Byte GetUserHDSleep()
  165. {
  166.     Byte    scratch;
  167.     
  168.     ReadPRAM(PRAM_BASE+prHDSleep_Offset, kByteSize, (char *)&scratch);
  169.     return scratch;
  170. }
  171.  
  172. #endif
  173.  
  174. /*
  175. ** SetSysSleep
  176. ** read the PRAM and return what the user set gSysSleep to be
  177. */
  178. void SetSysSleep(newValue)
  179. Byte newValue;
  180. {
  181.     SetPRAM(PRAM_BASE+prSysSleep_Offset, kByteSize, (char *)&newValue);
  182.     SetPMgrDirty();                                /* Tell PMgr to notice the change */
  183. }
  184.  
  185. /*
  186. ** SetHDSleep
  187. ** read the PRAM and return what the user set gHDSleep to be
  188. */
  189. void SetHDSleep(newValue)
  190. Byte newValue;
  191. {
  192.     SetPRAM(PRAM_BASE+prHDSleep_Offset, kByteSize, (char *)&newValue);
  193.     SetPMgrDirty();                                /* Tell PMgr to notice the change */
  194. }
  195.  
  196. /*
  197. ** InitPortableStuff
  198. ** set globals so they work with the Portable model we have.
  199. ** We only work with the Portable, PowerBook100, PowerBook140, and PowerBook170
  200. ** (Heck, who knows what the future brings?)
  201. */
  202. void InitPortableStuff()
  203. {
  204.     Byte    status;
  205.     Byte    power;
  206.     OSErr    err;
  207.     long    gestaltData;
  208.     Boolean    knownComputer;
  209.     long    globals;
  210.     long    powerManagerBase;
  211.  
  212.     Gestalt(gestaltPowerMgrAttr, &gestaltData);
  213.     
  214.     if (!(gestaltData & (1 << gestaltPMgrExists)) ) {
  215.         ExitToShell();
  216.     }
  217.  
  218.     Gestalt(gestaltMachineType, &gestaltData);
  219.     knownComputer = (gestaltData == gestaltPortable) 
  220.                     || (gestaltData == gestaltPowerBook100)
  221.                     || (gestaltData == gestaltPowerBook140) 
  222.                     || (gestaltData == gestaltPowerBook170);
  223.     
  224.     if (!knownComputer)
  225.         ExitToShell();
  226.  
  227.     err = BatteryStatus(&status, &power);
  228.     
  229.     gOnBattery = ~(status & chargerConnMask);    /* this ensures we'll do something */
  230.                                                 /* 1st time around */
  231. #if 0
  232.     gSysSleep = GetUserSysSleep();
  233.     gHDSleep = GetUserHDSleep();
  234. #endif
  235.  
  236.     Gestalt(gestaltMachineType, &gestaltData);
  237.     
  238.     switch (gestaltData) {
  239.         case gestaltPortable:
  240.         case gestaltPowerBook100:
  241.             gFlagsLocation = PRAM_BASE+prFlags_Offset_Portable;
  242.             break;
  243.         case gestaltPowerBook140:
  244.         case gestaltPowerBook145:
  245.         case gestaltPowerBook170:
  246.             gFlagsLocation = PRAM_BASE+prFlags_Offset;
  247.             break;
  248.         case gestaltDuo210:
  249.         case gestaltDuo230:
  250.         case gestaltPowerBook180:
  251.         case gestaltPowerBook160:
  252.         case gestaltPowerBook165c:
  253.             globals = * ((long *)(0x00000D18));
  254.             powerManagerBase = *((char *)globals + 0x55);    
  255.             gFlagsLocation = powerManagerBase+prFlags_Offset;
  256.             break;
  257.         default:
  258.             DebugStr("\punknown powerbook type");
  259.     }
  260. }
  261.  
  262. /*
  263.  * InitPrefs will load up the users selected system and HD sleep times from
  264.  * the preferences file. This is to avoid a problem with shutting down while
  265.  * attached to the mains.
  266.  */
  267.  
  268.  void InitPrefs() {
  269.      short vRefNum;
  270.     long  dirID;
  271.     
  272.     gSysSleep = 4*kUnitsOfSleep;
  273.     gHDSleep  = 4*kUnitsOfSleep;        // default in case this stuff breaks.
  274.     
  275.     if (noErr == FindFolder(kOnSystemDisk,kPreferencesFolderType,true,&vRefNum,&dirID) ) {
  276.         FSSpec        prefsFSSpec;
  277.         
  278.         if ( noErr == FSMakeFSSpec( vRefNum, dirID, "\pRegulator Prefs",&prefsFSSpec) ) {
  279.             short refNum;
  280.             refNum = FSpOpenResFile( &prefsFSSpec, fsRdPerm);
  281.             if ( refNum != -1 ) {
  282.                 Handle    hndl;
  283.                 
  284.                 UseResFile( refNum );
  285.                 hndl = Get1IndResource('Pref',1);
  286.                 if ( hndl ) {
  287.                     short    *ptr;
  288.                     
  289.                     HLock(hndl);
  290.                     ptr = *(short **)hndl;
  291.                     gSysSleep = *ptr * kUnitsOfSleep;
  292.                     ptr++;
  293.                     gHDSleep = *ptr * kUnitsOfSleep;
  294.                     if ( gSysSleep < gHDSleep )
  295.                         gHDSleep = gSysSleep;
  296.                     ReleaseResource( hndl );
  297.                     }
  298.                 FSClose ( refNum );
  299.                 }
  300.             }
  301.         }
  302.     }
  303.